//////////////////////////////////////////////////////////////////////////
// $Id: VertexFormat.cpp,v 1.1 2009/04/03 12:46:11 sunjun Exp $
//////////////////////////////////////////////////////////////////////////

#include "Local.h"

//////////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////////

NAMESPACE_BEGIN

//////////////////////////////////////////////////////////////////////////	

	VertexFormat::VertexFormat( const Context* rc ) : mHandle(NULL)
	{
		CHECK(rc);
		mRCPtr = (Context*)rc;
	}

	VertexFormat::~VertexFormat() 
	{
		if((IDirect3DVertexDeclaration9*)mHandle){((IDirect3DVertexDeclaration9*)mHandle)->Release(); mHandle = NULL;}
	}

	//////////////////////////////////////////////////////////////////////////

	/*
	====================
	handle
	====================
	*/
	INLINE HANDLE VertexFormat::handle() const
	{
		return mHandle;
	}

	/*
	====================
	load
	====================
	*/
	INLINE VOID VertexFormat::load( const FORMAT* formats )
	{
		// set the vertex element
		CHECK(formats);
		std::vector<D3DVERTEXELEMENT9>ves;
		I32 texcoord = 0;
		for( I32 i = 0; formats[i].stream != 0xFF; i++ )
		{
			D3DVERTEXELEMENT9 ve;
			ve.Stream = formats[i].stream;
			ve.Offset = formats[i].offset;
			ve.Type = formats[i].type;
			ve.Method = D3DDECLMETHOD_DEFAULT;
			ve.Usage = formats[i].semantic;
			ve.UsageIndex = 0;
			if(formats[i].semantic == VES_TEXCOORD) ve.UsageIndex = texcoord++;
			ves.push_back(ve);
		}
		D3DVERTEXELEMENT9 ve;
		ve.Stream = 0xFF;
		ve.Offset = 0;
		ve.Type = D3DDECLTYPE_UNUSED;
		ve.Method = 0;
		ve.Usage = 0;
		ve.UsageIndex = 0;
		ves.push_back(ve);

		// create the vertex declaration
		IDirect3DVertexDeclaration9* d3dVertexDeclaration = NULL;
		HRESULT hr = ((IDirect3DDevice9*)mRCPtr->handle())->CreateVertexDeclaration(&ves[0], &d3dVertexDeclaration);
		if(FAILED(hr)) MAssert(VA("VertexFormat::load : create the vertex declaration is failed(%s)!", DXGetErrorDescription(hr)));
		if((IDirect3DVertexDeclaration9*)mHandle){((IDirect3DVertexDeclaration9*)mHandle)->Release(); mHandle = NULL;}
		mHandle = (HANDLE)d3dVertexDeclaration;

		/*
		I32 offset = 0;
		switch(formats[i].type)
		{
		case VET_FLOAT1:
		offset += sizeof(F32);
		break;
		case VET_FLOAT2:
		offset += sizeof(F32)*2;
		break;
		case VET_FLOAT3:
		offset += sizeof(F32)*3;
		break;
		case VET_FLOAT4:
		offset += sizeof(F32)*4;
		break;
		case VET_COLOR:
		offset += sizeof(D3DCOLOR);
		break;
		case VET_UBYTE4:
		offset += sizeof(U8)*4;
		break;			
		case VET_SHORT2:
		offset += sizeof(I16)*2;
		break;
		case VET_SHORT4:
		offset += sizeof(I16)*4;
		break;
		case VET_UBYTE4N:
		offset += sizeof(U8)*4;
		break;
		case VET_SHORT2N:
		offset += sizeof(I16)*2;
		break;
		case VET_SHORT4N:
		offset += sizeof(I16)*4;
		break;
		case VET_USHORT2N:
		offset += sizeof(U16)*2;
		break;
		case VET_USHORT4N:
		offset += sizeof(U16)*4;
		break;
		default:
		MAssert(VA("VertexFormat::load : the vertex element type is unsupported(%d)!", formats[i].type));
		}
		*/
	}

//////////////////////////////////////////////////////////////////////////

NAMESPACE_END

//////////////////////////////////////////////////////////////////////////
